/******************************************************************************
 *                       B O M B E R M A N  2 0 1 2
 * 
 * File Name: Bomber.java
 * 
 * COP 4331 Summer 2012 Project
 * 
 * Authors: Trevor Mancuso, Chris Chiarella, Zach Hoyler, Daniel Martin
 * 
 * 
 * Description: This class is the bomber entity. This is either the player or
 * an AI opponent.
 * 
 ******************************************************************************/
package bomberman;
import java.awt.*;
import java.util.*;

public class Bomber extends Entity
{
    public static final int VIRUS_DURATION = 10; //Duration of the virus powerup
    public static final int AI_DELAY = 100; // Delay between AI routines in milliseconds
    
    private boolean hasVirus; //boolean for if the player has the virus
    private long gotVirus; // Time the virus was added
    
    private Image spriteUp, spriteLeft, spriteRight, spriteDown, spriteDead; //images for display
    
    //stats of the bomber, their player number, and if they are an a.i. or not
    public int bombPower;
    public int numBombs;
    public int maxBombs;
    public boolean remoteControl;
    private int playerNum;
    String color;
    private boolean AI;
    
    Bomberman game = null;
    public boolean alive = true;
    
    //variables for use by the ai for pathing
    int targetNum;
    private int pathX[];
    private int pathY[];
    private int pathPointer;
    private int currentPointer;
    private int moveNum;
    private int pathTurn;
    
    public Bomb lastBomb; // Remember last placed bomb for remote detonation
    
    //initialize the bomber
    Bomber(int player, Bomberman game, boolean AI)
    {
        //set all universal stats
        playerNum = player;
        this.AI = AI;
        bombPower = 1;
        maxBombs = 1;
        numBombs = 0;
        this.game = game;
        remoteControl = false;
        lastBomb = null;
        
        if (player == 1) //set the location, sprites and color for player one
          {
            color = "blue";
            spriteDown = Bomberman.Sprites.CHARACTER_BLUE_DOWN.getSprite();
            spriteLeft = Bomberman.Sprites.CHARACTER_BLUE_LEFT.getSprite();
            spriteRight = Bomberman.Sprites.CHARACTER_BLUE_RIGHT.getSprite();
            spriteUp = Bomberman.Sprites.CHARACTER_BLUE_UP.getSprite();
            spriteDead = Bomberman.Sprites.CHARACTER_BLUE_DEAD.getSprite();
            xPos = 0;
            yPos = 0;
            
            if(AI) //if they are an ai set up the extra info
            {
                targetNum = -1;
                pathX = new int[game.theGame.levelSize * game.theGame.levelSize];
                pathY = new int[game.theGame.levelSize * game.theGame.levelSize];
                pathPointer = 0;
                targetNum = 0;
                currentPointer = 0;
                moveNum = 10;
                pathTurn = 8;
            }
          }
        if (player == 2) //set the location, sprites and color for player two 
          {
            color = "red";
            spriteDown = Bomberman.Sprites.CHARACTER_RED_DOWN.getSprite();
            spriteLeft = Bomberman.Sprites.CHARACTER_RED_LEFT.getSprite();
            spriteRight = Bomberman.Sprites.CHARACTER_RED_RIGHT.getSprite();
            spriteUp = Bomberman.Sprites.CHARACTER_RED_UP.getSprite();
            spriteDead = Bomberman.Sprites.CHARACTER_RED_DEAD.getSprite();
            xPos = 29;
            yPos = 29;
            
            if(AI) //if they are an ai set up the extra info
            {
                targetNum = -1;
                pathX = new int[game.theGame.levelSize * game.theGame.levelSize];
                pathY = new int[game.theGame.levelSize * game.theGame.levelSize];
                pathPointer = 0;
                targetNum = 0;
                currentPointer = 0;
                moveNum = 10;
                pathTurn = 8;
            }
          }
        if(player == 3) //set the location, sprites and color for player three
        {
            color = "green";
            spriteDown = Bomberman.Sprites.CHARACTER_GREEN_DOWN.getSprite();
            spriteLeft = Bomberman.Sprites.CHARACTER_GREEN_LEFT.getSprite();
            spriteRight = Bomberman.Sprites.CHARACTER_GREEN_RIGHT.getSprite();
            spriteUp = Bomberman.Sprites.CHARACTER_GREEN_UP.getSprite();
            spriteDead = Bomberman.Sprites.CHARACTER_GREEN_DEAD.getSprite();
            
            xPos = 29; yPos = 0;
            
            if(AI) //if they are an ai set up the extra info
            {
                targetNum = -1;
                pathX = new int[game.theGame.levelSize * game.theGame.levelSize];
                pathY = new int[game.theGame.levelSize * game.theGame.levelSize];
                pathPointer = 0;
                targetNum = 0;
                currentPointer = 0;
                moveNum = 10;
                pathTurn = 8;
            }
        }
        
        setSprite(spriteDown);
    }
    
    //method returns whether or not the bomber is an ai
    public boolean isAI()
    {
        return AI;
    }
    
    //update the bombers sprite and collect powerups
    public void moveTo(int xPos, int yPos,int dir)
    {
        //get the current position
        this.xPos = xPos;
        this.yPos = yPos;
        
        //set the correct sprite based on the direction
        if(dir==1)
            setSprite(spriteUp);
        if(dir==2)
            setSprite(spriteRight);
        if(dir==3)
            setSprite(spriteDown);
        if(dir==4)
            setSprite(spriteLeft);
        
        //if there is a power up then collect it
        if(powerupCheck())
                game.theGame.getPowerup(xPos, yPos).collect(this);
    }
    
    //update the bombers location
    public void move(int direction)
    {
        if(alive) //if the bomber is alive
        {            
            if(direction == 1)//up
            {
                setSprite(spriteUp); //set the correct sprite
                
                if(collisionCheck(this.getX(),this.getY()-1)) //if there isn't anything in the way
                {
                    if(yPos != 0) //if you aren't at the top of the screen
                        yPos--; //move up
                }
            }
            else if(direction == 2)//right
            {
                setSprite(spriteRight); //set the correct sprite
                
                if(collisionCheck(this.getX()+1,this.getY()))  //if there isn't anything in the way
                {
                    if(xPos < Bomberman.getLevelSize() - 1) //if you aren't at the rightmost square
                        xPos++; //move right
                }
            }
            else if(direction == 3)//down
            {
                setSprite(spriteDown); //set the correct sprite
                
                if(collisionCheck(this.getX(),this.getY()+1)) //if there isn't anything in the way
                {
                    if(yPos < Bomberman.getLevelSize() - 1) //if not at the bottom most square
                        yPos++; //move down
                }
            }
            else if(direction == 4)//left
            {
                setSprite(spriteLeft); //set the correct sprite
                
                if(collisionCheck(this.getX()-1,this.getY())) //if there isn't anything in the way
                {
                    if(xPos != 0) //if not at the leftmost square
                        xPos--; //move left
                }
            }
            
            if(game.network) //if playing on the network send the move over
                game.handler.sendMove(xPos,yPos,direction);
            
            if(powerupCheck()) //check for powerups
                game.theGame.getPowerup(xPos, yPos).collect(this); //if there is one grab it
        }
    }
    
    //Return false if there is a barrier. True if there is none.
    public boolean collisionCheck(int x, int y)
    {
        if((x >= 0 && x <= 29) && (y >= 0 && y <= 29)) //if not checking out of bounds
        {
            if(game.theGame.getBarrier(x, y) != null) //if there is a barrier return false
                return false; 
            if(game.theGame.isBomb(x,y)) //if there is a bomb return false
                return false;
            
            for (Bomber b : game.bombers) //go through the bombers
                if (b != null && b != this && x == b.xPos && y == b.yPos) //if one of them matches the location being checked return false
                    return false;
            
        }
        else //if not in bounds return false
            return false;
        return true; //if it hasn't return false then return true
    }
    
    //returns the direction of the nearest bomb (0 = standing on it, 1 = up, 2 = right, 3 = down, 4 = left, -1 = none)
    public int bombScan(int x, int y, int radius)
    {
        //four booleans for whether to continue checking each direction (if a barrier is found no need to continue searching that direction)
        boolean checkUp = true;
        boolean checkDown = true;
        boolean checkLeft = true;
        boolean checkRight = true;
        
        if(game.theGame.getBomb(x,y) != null) //if there is a bomb on the same space as the bomber
            return 0; //return 0
        
        for(int i = 1; i < radius; i++) //a for loop to increase the distance checked
        {
            if(checkUp) //check upwards
            {
                boolean isBomb = game.theGame.getBomb(x, y - i) != null;
                if(isBomb) //if there is a bomb return 1
                {
                    return 1;
                }
                else if(game.theGame.isBarrier(x, y - i)) //if there is a barrier stop checking upwards
                {
                    checkUp = false;
                }
            }
            if(checkRight) //check right
            {
                if(game.theGame.getBomb(x + i, y) != null) //if there is a bomb return 2
                {
                    return 2;
                }
                else if(game.theGame.isBarrier(x + i, y)) //if there is a barrier stop checking to the right
                {
                    checkRight = false;
                }
            }
            if(checkDown) //check down
            {
                if(game.theGame.getBomb(x, y + i) != null) //if there is a bomb return 3
                {
                    return 3;
                }
                else if(game.theGame.isBarrier(x, y + i)) //if there is a barrier stop checking down
                {
                    checkDown = false;
                }
            }
            if(checkLeft) //check Left
            {    
                boolean isBomb = game.theGame.getBomb(x - i, y) != null;
                if(isBomb) //if there is a bomb return 3
                {
                    return 4;
                }
                else if(game.theGame.isBarrier(x - i, y)) //if there is a barrier stop checking to the left
                {
                    checkLeft = false;
                }
            }
        }
        return -1; //if no bomb is found return -1
    }

    //returns true if the A.I. heads for or lays a bomb in an attempt to attack the player
    public boolean attackPlayer(int targetX, int targetY)
    {
        boolean moved = false; //boolean for whether a move has been made or not (will be the boolean returned)
        boolean placeBomb = true;
        
        if(targetX - xPos < 3 && targetX - xPos > 0 && targetY == yPos) //if the target is to the right
        {
            for(int i = 0; i < targetX - xPos; i++) //check if there is a indestructable barrier in the way
            {
                if(game.theGame.getBarrier(xPos + i, yPos) != null)
                {
                    if(!game.theGame.getBarrier(xPos + i, yPos).isDestructable())
                        placeBomb = false;
                }
            }
            if(placeBomb) //if there wasn't then place a bomb
                placeBomb();
        }
        else if(xPos - targetX < 3 && xPos - targetX > 0 && targetY == yPos) //if the target is to the left
        {
            for(int i = 0; i < xPos - targetX; i++) //check if there is an indestructable barrier in the way
            {
                if(game.theGame.getBarrier(xPos - i, yPos) != null)
                {
                    if(!game.theGame.getBarrier(xPos - i, yPos).isDestructable())
                        placeBomb = false;
                }
            }
            if(placeBomb) //if not place a bomb
                placeBomb();
        }
        else if(targetY - yPos < 3 && targetY - yPos > 0 && targetX == xPos) //if the target is downwards
        {
            for(int i = 0; i < targetY - yPos; i++) //check if there is na indestructable barrier in the way
            {
                if(game.theGame.getBarrier(xPos, yPos + i) != null)
                {
                    if(!game.theGame.getBarrier(xPos, yPos + i).isDestructable())
                        placeBomb = false;
                }
            }
            if(placeBomb) //if not place a bomb
                placeBomb();
        }
        else if(yPos - targetY < 3 && yPos - targetY > 0 && targetX == xPos) //if the target is upwards
        {
            for(int i = 0; i < yPos - targetY; i++) //check if there is na indestructable barrier in the way
            {
                if(game.theGame.getBarrier(xPos, yPos - i) != null)
                {
                    if(!game.theGame.getBarrier(xPos, yPos - i).isDestructable())
                        placeBomb = false;
                }
            }
            if(placeBomb) //if not place a bomb
                placeBomb();
        }
        return moved;
    }
    
    //returns true if the square is not completely surrounded by barriers or bombs
    public boolean isNotDeadEnd(int x, int y)
    {
        if(game.theGame.getBarrier(x + 1, y) == null) //check for a barrier to the right
        {
            if(!game.theGame.isBomb(x + 1, y)) //check for a bomb to the right
               return true; //if neither is found then return true
        }
        if(game.theGame.getBarrier(x - 1, y) == null) //check for a barrier to the left
        {
            if(!game.theGame.isBomb(x - 1, y)) //check for a bomb to the left
                return true; //if neither is found then return true
        }
        if(game.theGame.getBarrier(x, y + 1) == null) //check for a barrier downwards
        {
            if(!game.theGame.isBomb(x, y + 1)) //check for a bomb downwards
               return true; //if neither is found then return true
        }
        if(game.theGame.getBarrier(x, y - 1) == null) //check for a barrier upwards
        {
            if(!game.theGame.isBomb(x, y - 1)) //check for a bomb upwards
               return true; //if neither is found then return true
        }
        return false; //if something is found in all directions return false
    }
    
    public void AI(Bomber targets[])
    {
        if(alive) //if the AI is not alive, don't do anything
        {
            if(moveNum >= 4) //if the move number is greater than 5 an action is allowed (used to regulate AI speed
            {
                int bombDirection = bombScan(xPos, yPos, 3); //run a bomb scan
                boolean moved = avoidBomb(bombDirection); //try to avoid a bomb if one is found and get a boolean for if a move is made
                if(targetNum == -1 || !targets[targetNum].alive) //if there is no target currently
                {
                    Random rand = new Random();
                    targetNum = rand.nextInt(targets.length - 1); //find a random target
                }
                int targetX = targets[targetNum].getX(), targetY = targets[targetNum].getY(); //get the target's location

                if(pathTurn == 8) //if the path hasn't been checked in 8 turns
                {
                    targetX = targets[targetNum].getX(); 
                    targetY = targets[targetNum].getY();
                    getPath(targetX, targetY); //get the path to the target
                    pathTurn = 0; //reset path turn
                    currentPointer = 1; //start at beginning of path
                }
                if(!attackPlayer(targetX, targetY)) //check to see if the player can be attacked, and if so attack the player
                {
                    int xy[] = findPowerup(); //look for nearby powerups
                    if(xy[0] != -1) //if a powerup is found
                    {
                        getPath(xy[0], xy[1]); //get the path to it
                        currentPointer = 1; //start at the beginning of the path
                    }
                    moveNum = 0; //reset moveNum to 0

                    //make integers for where the bomber should move to
                    int moveToX = pathX[currentPointer];
                    int moveToY = pathY[currentPointer];
                    
                    //increment the pathTurn and current point on path
                    currentPointer++;
                    pathTurn++;
                    
                    if(!moved && xPos > moveToX) //if a move hasn't been made yet and the next point on the path is to the left
                    {
                        if(collisionCheck(xPos - 1, yPos)) //do a collision check on the move to point
                        {
                            if(bombScan(xPos - 1, yPos, 3) == -1) //do a bombscan on that point (to make sure we don't step into the explosion path)
                            {
                                move(4); //move 
                                moved = true; //set moved to true
                                if(xPos - 1 == xy[0] && yPos == xy[1]) //if we were going to a powerup and reached it get a new path
                                    getPath(targetX, targetY);
                            }
                        }
                        else //if a barrier was in the way
                        {
                            if(game.theGame.getBarrier(xPos-1, yPos)!=null)
                            {
                                if(game.theGame.getBarrier(xPos - 1, yPos).isDestructable())
                                    placeBomb();
                            }
                        }
                    }
                    if(!moved && yPos < moveToY) //if a move hasn't been made yet and the next point on the path is downwards
                    {
                        if(collisionCheck(xPos, yPos + 1)) //do a collision check on the move to point
                        {
                            if(bombScan(xPos, yPos + 1, 3) == -1) //do a bombscan on that point (to make sure we don't step into the explosion path)
                            {
                                move(3); //move
                                moved = true; //set moved to true
                                if(xPos == xy[0] && yPos + 1 == xy[1]) //if we were going to a powerup and reached it get a new path
                                    getPath(targetX, targetY);
                            }
                        }
                        else //if a barrier was in the way
                        {
                            if(game.theGame.getBarrier(xPos, yPos+1)!=null)
                            {
                                if(game.theGame.getBarrier(xPos, yPos + 1).isDestructable())
                                    placeBomb();
                            }
                        }
                    }
                    if(!moved && xPos < moveToX) //if a move hasn't been made yet and the next point on the path is to the right
                    {
                        if(collisionCheck(xPos + 1, yPos)) //do a collision check on the move to point
                        {
                            if(bombScan(xPos + 1, yPos, 3) == -1) //do a bombscan on that point (to make sure we don't step into the explosion path)
                            {
                                move(2); //move
                                moved = true; //set moved to true
                                if(xPos + 1 == xy[0] && yPos == xy[1])  //if we were going to a powerup and reached it get a new path
                                    getPath(targetX, targetY);
                            }
                        }
                        else //if a barrier was in the way
                        {
                            if(game.theGame.getBarrier(xPos+1, yPos) != null)
                            {
                                if(game.theGame.getBarrier(xPos + 1, yPos).isDestructable())
                                    placeBomb();
                            }
                        }
                    }
                    if(!moved && yPos > moveToY) //if a move hasn't been made yet and the next point on the path is upwards
                    {
                        if(collisionCheck(xPos, yPos - 1)) //do a collision check on the move to point
                        {
                            if(bombScan(xPos, yPos - 1, 3) == -1) //do a bombscan on that point (to make sure we don't step into the explosion path)
                            {
                                move(1); //move
                                moved = true; //set moved to true
                                if(xPos == xy[0] && yPos - 1 == xy[1])  //if we were going to a powerup and reached it get a new path
                                    getPath(targetX, targetY);
                            }
                        }
                        else //if a barrier was in the way
                        {
                            if(game.theGame.getBarrier(xPos, yPos - 1) != null)
                            {
                                if(game.theGame.getBarrier(xPos, yPos - 1).isDestructable())
                                    placeBomb();
                            }
                        }
                    }
                }
            }
            else //else (not the right turn to move) increment the moveNum
                moveNum++;
        }
    }
    
    //get the path from current position to the (x,y) square
    private void getPath(int x, int y)
    {
        pathPointer = 0; //set the path pointer to 0
        pathX[pathPointer] = xPos; //the first point is the current position
        pathY[pathPointer] = yPos;
        //make a 2D boolean array for all the squares in the level and set them to false
        boolean visited[][] = new boolean[game.theGame.levelSize][game.theGame.levelSize];
        for(int i = 0; i < game.theGame.levelSize; i++)
            for(int n = 0; n < game.theGame.levelSize; n++)
                visited[i][n] = false;
        visited[pathX[pathPointer]][pathY[pathPointer]] = true; //set the current square to true
        
        for(int i = 1; i < game.theGame.levelSize * game.theGame.levelSize; i++) //set all points in the path to -1
        {
            pathX[i] = -1;
            pathY[i] = -1;
        }
        
        while(pathPointer != -1 && (pathX[pathPointer] != x || pathY[pathPointer] != y)) //while not at the destination (or the stack hasn't popped all locations)
        {
            visited[pathX[pathPointer]][pathY[pathPointer]] = true; //current square is visited
            if(x <= pathX[pathPointer] && y <= pathY[pathPointer]) //target is to the upperleft
            {
                if(pathX[pathPointer] - 1 >= 0 && !visited[pathX[pathPointer] - 1][pathY[pathPointer]]) //try to go left
                {
                    visited[pathX[pathPointer] - 1][pathY[pathPointer]] = true;
                    if((game.theGame.getBarrier(pathX[pathPointer] - 1,pathY[pathPointer]) == null) || game.theGame.getBarrier(pathX[pathPointer] - 1,pathY[pathPointer]) != null && game.theGame.getBarrier(pathX[pathPointer] - 1,pathY[pathPointer]).isDestructable)
                    {
                        pathX[pathPointer + 1] = pathX[pathPointer] - 1;
                        pathY[pathPointer + 1] = pathY[pathPointer];
                        pathPointer++;
                    }
                }
                else if(pathY[pathPointer] - 1 >= 0 && !visited[pathX[pathPointer]][pathY[pathPointer] - 1]) //try to go up
                {
                    visited[pathX[pathPointer]][pathY[pathPointer] - 1] = true;
                    if((game.theGame.getBarrier(pathX[pathPointer],pathY[pathPointer] - 1) == null) || game.theGame.getBarrier(pathX[pathPointer],pathY[pathPointer] - 1) != null && game.theGame.getBarrier(pathX[pathPointer],pathY[pathPointer] - 1).isDestructable)
                    {
                        pathX[pathPointer + 1] = pathX[pathPointer];
                        pathY[pathPointer + 1] = pathY[pathPointer] - 1;
                        pathPointer++;
                    }
                }
                else if(pathY[pathPointer] + 1 < 30 && !visited[pathX[pathPointer]][pathY[pathPointer] + 1]) //try to go down
                {
                    visited[pathX[pathPointer]][pathY[pathPointer] + 1] = true;
                    if((game.theGame.getBarrier(pathX[pathPointer],pathY[pathPointer] + 1) == null) || game.theGame.getBarrier(pathX[pathPointer],pathY[pathPointer] + 1) != null && game.theGame.getBarrier(pathX[pathPointer],pathY[pathPointer] + 1).isDestructable)
                    {
                        pathX[pathPointer + 1] = pathX[pathPointer];
                        pathY[pathPointer + 1] = pathY[pathPointer] + 1;
                        pathPointer++;
                    }
                }   
                else if(pathX[pathPointer] + 1 < 30 && !visited[pathX[pathPointer] + 1][pathY[pathPointer]]) //try to go right
                {
                    visited[pathX[pathPointer] + 1][pathY[pathPointer]] = true;
                    if((game.theGame.getBarrier(pathX[pathPointer] + 1,pathY[pathPointer]) == null) || game.theGame.getBarrier(pathX[pathPointer] + 1,pathY[pathPointer]) != null && game.theGame.getBarrier(pathX[pathPointer] + 1,pathY[pathPointer]).isDestructable)
                    {
                        pathX[pathPointer + 1] = pathX[pathPointer] + 1;
                        pathY[pathPointer + 1] = pathY[pathPointer];
                        pathPointer++;
                    }
                }
                else //otherwise pop the current location
                    pathPointer--;
            }
            else if(x >= pathX[pathPointer] && y <= pathY[pathPointer]) //if the target is to the upperright
            {
                if(pathX[pathPointer] + 1  < 30 && !visited[pathX[pathPointer] + 1][pathY[pathPointer]]) //try to go right
                {
                    visited[pathX[pathPointer] + 1][pathY[pathPointer]] = true;
                    if((game.theGame.getBarrier(pathX[pathPointer] + 1,pathY[pathPointer]) == null) || game.theGame.getBarrier(pathX[pathPointer] + 1,pathY[pathPointer]) != null && game.theGame.getBarrier(pathX[pathPointer] + 1,pathY[pathPointer]).isDestructable)
                    {
                        pathX[pathPointer + 1] = pathX[pathPointer] + 1;
                        pathY[pathPointer + 1] = pathY[pathPointer];
                        pathPointer++;
                    }
                }
                else if(pathY[pathPointer] - 1 >= 0 && !visited[pathX[pathPointer]][pathY[pathPointer] - 1]) //try to go up
                {
                    visited[pathX[pathPointer]][pathY[pathPointer] - 1] = true;
                    if((game.theGame.getBarrier(pathX[pathPointer],pathY[pathPointer] - 1) == null) || game.theGame.getBarrier(pathX[pathPointer],pathY[pathPointer] - 1) != null && game.theGame.getBarrier(pathX[pathPointer],pathY[pathPointer] - 1).isDestructable)
                    {
                        pathX[pathPointer + 1] = pathX[pathPointer];
                        pathY[pathPointer + 1] = pathY[pathPointer] - 1;
                        pathPointer++;
                    }
                }
                else if(pathY[pathPointer] + 1  < 30 && !visited[pathX[pathPointer]][pathY[pathPointer] + 1]) //try to go down
                {
                    visited[pathX[pathPointer]][pathY[pathPointer] + 1] = true;
                    if((game.theGame.getBarrier(pathX[pathPointer],pathY[pathPointer] + 1) == null) || game.theGame.getBarrier(pathX[pathPointer],pathY[pathPointer] + 1) != null && game.theGame.getBarrier(pathX[pathPointer],pathY[pathPointer] + 1).isDestructable)
                    {
                        pathX[pathPointer + 1] = pathX[pathPointer];
                        pathY[pathPointer + 1] = pathY[pathPointer] + 1;
                        pathPointer++;
                    }
                }
                else if(pathX[pathPointer] - 1 >= 0 && !visited[pathX[pathPointer] - 1][pathY[pathPointer]]) //try to go left
                {
                    visited[pathX[pathPointer] - 1][pathY[pathPointer]] = true;
                    if((game.theGame.getBarrier(pathX[pathPointer] - 1,pathY[pathPointer]) == null) || game.theGame.getBarrier(pathX[pathPointer] - 1,pathY[pathPointer]) != null && game.theGame.getBarrier(pathX[pathPointer] - 1,pathY[pathPointer]).isDestructable)
                    {
                        pathX[pathPointer + 1] = pathX[pathPointer] - 1;
                        pathY[pathPointer + 1] = pathY[pathPointer];
                        pathPointer++;
                    }
                }
                else //otherwise pop the current location
                    pathPointer--;
            }
            else if(x >= pathX[pathPointer] && y >= pathY[pathPointer]) //if the target is to the lowerright
            {
                if(pathY[pathPointer] + 1  < 30 && !visited[pathX[pathPointer]][pathY[pathPointer] + 1]) //try to go down
                {
                    visited[pathX[pathPointer]][pathY[pathPointer] + 1] = true;
                    if((game.theGame.getBarrier(pathX[pathPointer],pathY[pathPointer] + 1) == null) || game.theGame.getBarrier(pathX[pathPointer],pathY[pathPointer] + 1) != null && game.theGame.getBarrier(pathX[pathPointer],pathY[pathPointer] + 1).isDestructable)
                    {
                        pathX[pathPointer + 1] = pathX[pathPointer];
                        pathY[pathPointer + 1] = pathY[pathPointer] + 1;
                        pathPointer++;
                    }
                }                   
                else if(pathX[pathPointer] + 1  < 30 && !visited[pathX[pathPointer] + 1][pathY[pathPointer]]) //try to go right
                {
                    visited[pathX[pathPointer] + 1][pathY[pathPointer]] = true;
                    if((game.theGame.getBarrier(pathX[pathPointer] + 1,pathY[pathPointer]) == null) || game.theGame.getBarrier(pathX[pathPointer] + 1,pathY[pathPointer]) != null && game.theGame.getBarrier(pathX[pathPointer] + 1,pathY[pathPointer]).isDestructable)
                    {
                        pathX[pathPointer + 1] = pathX[pathPointer] + 1;
                        pathY[pathPointer + 1] = pathY[pathPointer];
                        pathPointer++;
                    }
                }
                else if(pathX[pathPointer] - 1 >= 0 && !visited[pathX[pathPointer] - 1][pathY[pathPointer]]) //try to go left
                {
                    visited[pathX[pathPointer] - 1][pathY[pathPointer]] = true;
                    if((game.theGame.getBarrier(pathX[pathPointer] - 1,pathY[pathPointer]) == null) || game.theGame.getBarrier(pathX[pathPointer] - 1,pathY[pathPointer]) != null && game.theGame.getBarrier(pathX[pathPointer] - 1,pathY[pathPointer]).isDestructable)
                    {
                        pathX[pathPointer + 1] = pathX[pathPointer] - 1;
                        pathY[pathPointer + 1] = pathY[pathPointer];
                        pathPointer++;
                    }
                }
                else if(pathY[pathPointer] - 1 >= 0 && !visited[pathX[pathPointer]][pathY[pathPointer] - 1]) //try to go up
                {
                    visited[pathX[pathPointer]][pathY[pathPointer] - 1] = true;
                    if((game.theGame.getBarrier(pathX[pathPointer],pathY[pathPointer] - 1) == null) || game.theGame.getBarrier(pathX[pathPointer],pathY[pathPointer] - 1) != null && game.theGame.getBarrier(pathX[pathPointer],pathY[pathPointer] - 1).isDestructable)
                    {
                        pathX[pathPointer + 1] = pathX[pathPointer];
                        pathY[pathPointer + 1] = pathY[pathPointer] - 1;
                        pathPointer++;
                    }
                }
                else //otherwise pop the current locations
                    pathPointer--;
            }            
            else if(x <= pathX[pathPointer] && y >= pathY[pathPointer]) //if the target is to the lowerleft
            {
                if(pathY[pathPointer] + 1  < 30 && !visited[pathX[pathPointer]][pathY[pathPointer] + 1]) //try to go down
                {
                    visited[pathX[pathPointer]][pathY[pathPointer] + 1] = true;
                    if((game.theGame.getBarrier(pathX[pathPointer],pathY[pathPointer] + 1) == null) || game.theGame.getBarrier(pathX[pathPointer],pathY[pathPointer] + 1) != null && game.theGame.getBarrier(pathX[pathPointer],pathY[pathPointer] + 1).isDestructable)
                    {
                        pathX[pathPointer + 1] = pathX[pathPointer];
                        pathY[pathPointer + 1] = pathY[pathPointer] + 1;
                        pathPointer++;
                    }
                }  
                else if(pathX[pathPointer] - 1 >= 0 && !visited[pathX[pathPointer] - 1][pathY[pathPointer]]) //try to go left
                {
                    visited[pathX[pathPointer] - 1][pathY[pathPointer]] = true;
                    if((game.theGame.getBarrier(pathX[pathPointer] - 1,pathY[pathPointer]) == null) || game.theGame.getBarrier(pathX[pathPointer] - 1,pathY[pathPointer]) != null && game.theGame.getBarrier(pathX[pathPointer] - 1,pathY[pathPointer]).isDestructable)
                    {
                        pathX[pathPointer + 1] = pathX[pathPointer] - 1;
                        pathY[pathPointer + 1] = pathY[pathPointer];
                        pathPointer++;
                    }
                }                 
                else if(pathX[pathPointer] + 1 < 30 && !visited[pathX[pathPointer] + 1][pathY[pathPointer]]) //try to go right
                {
                    visited[pathX[pathPointer] + 1][pathY[pathPointer]] = true;
                    if((game.theGame.getBarrier(pathX[pathPointer] + 1,pathY[pathPointer]) == null) || game.theGame.getBarrier(pathX[pathPointer] + 1,pathY[pathPointer]) != null && game.theGame.getBarrier(pathX[pathPointer] + 1,pathY[pathPointer]).isDestructable)
                    {
                        pathX[pathPointer + 1] = pathX[pathPointer] + 1;
                        pathY[pathPointer + 1] = pathY[pathPointer];
                        pathPointer++;
                    }
                }
                
                else if(pathY[pathPointer] - 1 >= 0 && !visited[pathX[pathPointer]][pathY[pathPointer] - 1]) //try to go up
                {
                    visited[pathX[pathPointer]][pathY[pathPointer] - 1] = true;
                    if((game.theGame.getBarrier(pathX[pathPointer],pathY[pathPointer] - 1) == null) || game.theGame.getBarrier(pathX[pathPointer],pathY[pathPointer] - 1) != null && game.theGame.getBarrier(pathX[pathPointer],pathY[pathPointer] - 1).isDestructable)
                    {
                        pathX[pathPointer + 1] = pathX[pathPointer];
                        pathY[pathPointer + 1] = pathY[pathPointer] - 1;
                        pathPointer++;
                    }
                }
                else //otherwise pop the current locations
                    pathPointer--;
            }   
        }
    }
    
    //return the x and y of any nearby powerups or (-1,-1) if there are none
    int[] findPowerup()
    {
        int xy[] = new int[2]; //xy[0] = x, xy[1] = y
        for(int i = 0; i < 3; i++) //check two squares away
        {
            if(game.theGame.getPowerup(xPos - i, yPos) != null) //check to the left
            {
                xy[0] = xPos - i;
                xy[1] = yPos;
                return xy;
            }
            else if(game.theGame.getPowerup(xPos + i, yPos) != null) //check to the right
            {
                xy[0] = xPos + i;
                xy[1] = yPos;
                return xy;
            }
            else if(game.theGame.getPowerup(xPos, yPos - i) != null) //check up
            {
                xy[0] = xPos;
                xy[1] = yPos - i;
                return xy;
            }
            else if(game.theGame.getPowerup(xPos, yPos + i) != null) //check down
            {
                xy[0] = xPos;
                xy[1] = yPos + i;
                return xy;
            }
        }
        xy[0] = -1;
        xy[1] = -1;
        
        return xy; //return (-1,-1) if nothing was found
    }
    
    private boolean avoidBomb(int bombDirection)
    {
        boolean moved = false;
        if(bombDirection != -1)
        {
            if(bombDirection == 0) // standing on it
            {
                if(!moved && collisionCheck(xPos - 1, yPos)) //try to move left
                {
                    if(isNotDeadEnd(xPos - 1, yPos))
                    {
                        move(4);
                        moved = true;
                    }
                }
                if(!moved && collisionCheck(xPos + 1, yPos)) //try to move right
                {
                    if(isNotDeadEnd(xPos + 1, yPos))
                    {
                        move(2);
                        moved = true;
                    }
                }
                if(!moved && collisionCheck(xPos, yPos + 1)) //try to run down
                {
                    if(isNotDeadEnd(xPos, yPos + 1))
                    {
                        move(3);
                        moved = true;
                    }
                }
                if(!moved && collisionCheck(xPos, yPos - 1)) //try to move up
                {
                    if(isNotDeadEnd(xPos, yPos - 1))
                    {
                        move(1);
                        moved = true;
                    }
                }
            }
            if(bombDirection == 1) //up
            {
                if(!moved && collisionCheck(xPos - 1, yPos)) //move left
                {
                    if(bombScan(xPos - 1, yPos, 3) == -1)
                    {
                        move(4);
                        moved = true;
                    }
                }
                if(!moved && collisionCheck(xPos + 1, yPos)) //move right
                {
                    if(bombScan(xPos + 1, yPos, 3) == -1)
                    {
                        move(2);
                        moved = true;
                    }
                }
                if(!moved && collisionCheck(xPos, yPos + 1)) //move down
                {
                    move(3);
                    moved = true;
                }
            }
            else if(bombDirection == 2) //right
            {
                if(!moved && collisionCheck(xPos, yPos + 1)) //move down
                {
                    if(bombScan(xPos, yPos + 1, 3) == -1)
                    {
                        move(3);
                        moved = true;
                    }
                }
                if(!moved && collisionCheck(xPos, yPos - 1)) //move up
                {
                    if(bombScan(xPos, yPos - 1, 3) == -1)
                    {
                        move(1);
                        moved = true;
                    }
                }
                if(!moved && collisionCheck(xPos - 1, yPos)) //move left
                {
                    move(4);
                    moved = true;
                }
            }
            else if(bombDirection == 3) //down
            {
                if(!moved && collisionCheck(xPos - 1, yPos)) //move left
                {
                    if(bombScan(xPos - 1, yPos, 3) == -1)
                    {
                        move(4);
                        moved = true;
                    }
                }
                if(!moved && collisionCheck(xPos + 1, yPos)) //move right
                {
                    if(bombScan(xPos + 1, yPos, 3) == -1)
                    {
                        move(2);
                        moved = true;
                    }
                }
                if(!moved && collisionCheck(xPos, yPos - 1)) //move up
                {
                    move(1);
                    moved = true;
                }
            }
            else if(bombDirection == 4) //left
            {
                if(!moved && collisionCheck(xPos, yPos + 1)) //move down
                {
                    if(bombScan(xPos, yPos + 1, 3) == -1)
                    {
                        move(3);
                        moved = true;
                    }
                }
                if(!moved && collisionCheck(xPos, yPos - 1)) //move up
                {
                    if(bombScan(xPos, yPos - 1, 3) == -1)
                    {
                        move(1);
                        moved = true;
                    }
                }
                if(!moved && collisionCheck(xPos + 1, yPos)) //move right
                {
                    move(2);
                    moved = true;
                }
            }
        }
        return moved; //return whether or not a move was made
    }
    
    //places a bomb
    public void placeBomb()
    {
        if(alive) //if the bomber is alive
        {
            if(numBombs < maxBombs) //if the bomber hasn't placed his max number of bombs
            {
                if(game.theGame.getBomb(xPos, yPos) == null) // if there isn't a bomb already in the bomber's square
                {
                    game.theGame.bombArray[this.getX()][this.getY()] = new Bomb(this.getX(),this.getY(),bombPower,3,game,this); //add the bomb to the level's bomb array
                    lastBomb = game.theGame.bombArray[this.getX()][this.getY()]; //set it as the last bomb (for remote detonation)
                    numBombs++; //increment the number of bombs
                    if(game.network) //if on a network
                        game.handler.sendBomb(xPos, yPos, bombPower,playerNum); //send the bomb to the other player
                }
            }
        }
    }
    
    //kill the bomber
    public void kill()
    {
        if (alive) //if currently alive
        {
            Sound.DEATH.play(); //play the death sound
            setSprite(spriteDead); //set the death sprite
            System.out.println(playerNum + " is dead!"); //output the player is dead
            alive = false; //set alive to false
        }
    }
    
    //return true if there is a powerup in the square, false otherwise
    public boolean powerupCheck()
    {
        if(game.theGame.getPowerup(xPos, yPos)!=null) //if there is a powerup
            return true; //return true
        else //otherwise false
            return false;
    }
    
    //return whether or noth the bomber is alive
    public boolean isAlive()
    {
        return alive;
    }
    
    //remote detonate the bomb
    public void remoteDetonate()
    {
        if (lastBomb != null && remoteControl) //if the last bomb exists and you have the remote powerup
        {
            lastBomb.explode(); //explode the last bomb
            lastBomb = null; //make lastBomb null
        }
    }
    
    //give the bomber the virus
    public void giveVirus()
    {
        hasVirus = true; //hasVirus becomes true
        gotVirus = System.currentTimeMillis(); //keep track of when the virus was gained
    }
    
    //check to see if the bomber still has the virus
    public void virusTick()
    {
        if (hasVirus) //if they have it
        {
            if (System.currentTimeMillis() - gotVirus > VIRUS_DURATION*1000) //check when they got it to the current time and see if enough time has passed
            {
                hasVirus = false; //set it to false
                System.out.println("Virus gone!"); //output that the virus is gone
            }
        
            placeBomb(); //place a bomb
        }
    }
}